1 /*
2 * Copyright (C) 2009 The Guava Authors
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 package com.google.common.collect;
18
19 import static com.google.common.base.Preconditions.checkPositionIndex;
20
21 import com.google.common.annotations.GwtCompatible;
22
23 import java.util.ListIterator;
24 import java.util.NoSuchElementException;
25
26 /**
27 * This class provides a skeletal implementation of the {@link ListIterator}
28 * interface across a fixed number of elements that may be retrieved by
29 * position. It does not support {@link #remove}, {@link #set}, or {@link #add}.
30 *
31 * @author Jared Levy
32 */
33 @GwtCompatible
34 abstract class AbstractIndexedListIterator<E>
35 extends UnmodifiableListIterator<E> {
36 private final int size;
37 private int position;
38
39 /**
40 * Returns the element with the specified index. This method is called by
41 * {@link #next()}.
42 */
43 protected abstract E get(int index);
44
45 /**
46 * Constructs an iterator across a sequence of the given size whose initial
47 * position is 0. That is, the first call to {@link #next()} will return the
48 * first element (or throw {@link NoSuchElementException} if {@code size} is
49 * zero).
50 *
51 * @throws IllegalArgumentException if {@code size} is negative
52 */
53 protected AbstractIndexedListIterator(int size) {
54 this(size, 0);
55 }
56
57 /**
58 * Constructs an iterator across a sequence of the given size with the given
59 * initial position. That is, the first call to {@link #nextIndex()} will
60 * return {@code position}, and the first call to {@link #next()} will return
61 * the element at that index, if available. Calls to {@link #previous()} can
62 * retrieve the preceding {@code position} elements.
63 *
64 * @throws IndexOutOfBoundsException if {@code position} is negative or is
65 * greater than {@code size}
66 * @throws IllegalArgumentException if {@code size} is negative
67 */
68 protected AbstractIndexedListIterator(int size, int position) {
69 checkPositionIndex(position, size);
70 this.size = size;
71 this.position = position;
72 }
73
74 @Override
75 public final boolean hasNext() {
76 return position < size;
77 }
78
79 @Override
80 public final E next() {
81 if (!hasNext()) {
82 throw new NoSuchElementException();
83 }
84 return get(position++);
85 }
86
87 @Override
88 public final int nextIndex() {
89 return position;
90 }
91
92 @Override
93 public final boolean hasPrevious() {
94 return position > 0;
95 }
96
97 @Override
98 public final E previous() {
99 if (!hasPrevious()) {
100 throw new NoSuchElementException();
101 }
102 return get(--position);
103 }
104
105 @Override
106 public final int previousIndex() {
107 return position - 1;
108 }
109 }